//
//  CommandManager.m
//  Command
//
//  Created by Hechun on 2020/11/7.
//

#import "CommandManager.h"

@implementation CommandManager

+ (instancetype)sharedInstance {
    static CommandManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 模拟耗时操作,给其他线程进入提供机会
        sleep(3);
        instance = [[super allocWithZone:NULL] init];
        NSLog(@"synchronizedManager 只执行一次是对的");
    });
    
    return instance;
}

// 方式1，使用synchronized最简单
+ (instancetype)synchronizedManager {
    static CommandManager *instance = nil;
    @synchronized (self) {
        if (instance == nil) {
            // 模拟耗时操作,给其他线程进入提供机会
            sleep(3);
            instance = [[super allocWithZone:NULL] init];
            NSLog(@"synchronizedManager 只执行一次是对的");
        }
    }
    
    return instance;
}


// 方式2，使用dispatch_semaphore,需要多一些操作,NSLock同理

static dispatch_semaphore_t sem = nil;
+ (void)initialize {
    if (sem == nil) {
        sem = dispatch_semaphore_create(1);
    }
}
// https://blog.csdn.net/u014600626/article/details/102862777
+ (instancetype)semaphoreManager {
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    static CommandManager *instance = nil;
    if (instance == nil) {
        // 模拟耗时操作,给其他线程进入提供机会
        sleep(3);
        instance = [[super allocWithZone:NULL] init];
        NSLog(@"semaphoreManager 只执行一次是对的");
    }
    dispatch_semaphore_signal(sem);
    return instance;
    
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    return [self synchronizedManager];
}

+ (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion {
    if (cmd) {
        // 如果命令正在执行不做处理, 否则添加执行命令
        if (![self isExecutingCommand:cmd]) {
            // 添加到命令容器当中
            [[[self synchronizedManager] arrayCommands] addObject:cmd];
            // 设置命令执行完成的回调
            cmd.completion = completion;
            // 执行命令
            [cmd execute];
        }
        
    }
}

/// 取消命令
+ (void)cancelCommand:(Command *)cmd {
    if (cmd) {
        // 从命令容器中移除
        [[[self synchronizedManager] arrayCommands] removeObject:cmd];
        // 取消执行命令
        [cmd cancel];
    }
}

/// 判断当前命令是否正在执行
+ (BOOL)isExecutingCommand:(Command *)cmd {
    if (cmd) {
        NSArray *cmds = [[self synchronizedManager] arrayCommands];
        for (Command *aCmd in cmds) {
            // 当前命令正在执行
            if (cmd == aCmd) {
                return YES;
                break;;
            }
        }
    }
    
    return NO;
}

- (NSMutableArray<Command *> *)arrayCommands {
    if (!_arrayCommands) {
        _arrayCommands = [NSMutableArray array];
    }
    
    return _arrayCommands;
}

@end
